<template>
  <h2 :class="{ compact: props.compact }">得分排行榜</h2>
  <span v-if="loading" class="loader"></span>
  <div class="leaderboard" :class="{ compact: props.compact }">
    <div
      v-for="(item, i) in items"
      class="leaderboard-item"
      :class="{
        first: i === 0 && !props.compact,
        second: i === 1 && !props.compact,
        third: i === 2 && !props.compact,
      }"
    >
      <span class="number">{{ i + 1 }}.</span>
      <span class="name">{{ item.username }}</span>
      <span class="score">{{ prettifyScore(item.score) }} 分</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { Settings } from '../game/models/Settings';
import { Ref, ref } from 'vue';
import { onMounted } from 'vue';
import { _getRank, _postScore } from '~/libs/apis/rank';
import { prettifyScore } from '~/libs/helpers';

const props = defineProps(['compact']);

type LeaderBoardItem = { username: string; score: number };

const items: Ref<LeaderBoardItem[]> = ref([]);
const loading = ref(true);

onMounted(async () => {
  const leaderBoard: LeaderBoardItem[] = await _getRank();
  if (leaderBoard.length === 0) return;

  items.value = leaderBoard;
  loading.value = false;

  // Fetch new leaderboard every few minutes
  setInterval(
    async () => {
      const newLeaderBoard: LeaderBoardItem[] = await _getRank();
      if (newLeaderBoard.length === 0) return;

      items.value = newLeaderBoard;
    },
    (props.compact ? 3 : 6) * 60 * 1000,
  );
});

function submitNewRun(settings: Settings, score: number) {
  const existingRecord = items.value.find(
    (i) => i.username === settings.username,
  );
  _postScore(settings.username, score).then(null, () => {
    console.log('Post Failure!');
  });
  if (existingRecord && existingRecord.score < score) {
    existingRecord.score = score;
  } else if (!existingRecord && settings.username) {
    items.value.push({ username: settings.username, score });
  }

  items.value.sort((a, b) => b.score - a.score);
  items.value.splice(20);

  // TODO submit score
  // submitRun(settings, score);
}

defineExpose({
  submitNewRun,
});
</script>

<style lang="scss" scoped>
.loader {
  display: block;
  transform-origin: center center;
  clip-path: polygon(0 0, 100% 0, 100% 50%, 69% 66%, 56% 100%, 0 100%);
  animation: loader 1000ms linear infinite;
  margin: 20px auto;
  border: 3px solid #fff;
  border-radius: 50%;
  width: 36px;
  height: 36px;
}

@keyframes loader {
  0% {
    transform: rotateZ(0deg);
  }
  100% {
    transform: rotateZ(360deg);
  }
}

.leaderboard {
  h2 {
    margin-bottom: 10px;
    font-size: 32px;
    font-family: 'Bree serif';
    letter-spacing: 3px;
    text-align: center;

    &.compact {
      margin-bottom: 6px;
      color: rgba(#fff, 0.6);
      font-weight: 400;
      font-size: 20px;
      letter-spacing: 2px;
    }
  }

  .leaderboard-item {
    display: flex;
    margin-bottom: 4px;
    max-height: 20px;
    line-height: 20px;
    --color: var(--primary);

    .number {
      display: block;
      margin-left: 10px;
      background-color: var(--color);
      width: 35px;
      color: #fff;
      line-height: inherit;
      text-align: center;
    }

    .name {
      display: block;
      background-color: #fff;
      padding-left: 10px;
      width: 200px;
      color: var(--color);
      line-height: inherit;
    }

    .score {
      display: block;
      background-color: var(--color);
      padding-right: 10px;
      width: 120px;
      color: #fff;
      line-height: inherit;
      text-align: end;
    }

    &.first,
    &.second,
    &.third {
      margin-bottom: 6px;
      max-height: 30px;
      font-size: 20px;
      line-height: 30px;

      .number {
        clip-path: polygon(35% 0, 100% 0, 100% 100%, 0% 100%);
        margin-left: 0;
        padding-right: 8px;
        width: 45px;
        text-align: end;
      }

      @media (max-width: 1400px) {
        font-size: 16px;
      }
    }

    &.first {
      --color: #eec01d;
    }

    &.second {
      --color: #a8a8a8;
    }

    &.third {
      --color: #ee8517;
    }
  }

  &.compact {
    max-height: 250px;
    overflow-y: scroll;
    -ms-overflow-style: none;
    scrollbar-width: none;

    .number {
      background-color: rgba(#70a480, 0.7);
      color: rgba(#fff, 0.4);
    }

    .name {
      background-color: rgba(#fff, 0.3);
      width: 160px;
      color: rgba(#70a480, 0.8);
    }

    .score {
      background-color: rgba(#70a480, 0.7);
      color: rgba(#fff, 0.4);
    }

    &::-webkit-scrollbar {
      width: 0;
    }
  }

  &:not(.compact) {
    @media (max-width: 1400px) {
      .leaderboard-item {
        .name {
          width: 150px;
        }

        .score {
          width: 100px;
        }
      }
    }
  }

  @media (max-width: 1300px) {
    &.compact {
      position: unset;
      transform: none;
      padding: 0 10px 50px;

      .leaderboard-item {
        justify-content: center;
      }
    }
  }

  @media (max-width: 1000px) {
    &.compact {
      .leaderboard-item {
        font-size: 14px;

        .number {
          width: 25px;
        }

        .name {
          width: 130px;
        }

        .score {
          width: 85px;
        }
      }
    }
  }
}
</style>
